home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Ports / alfa / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-23  |  6.3 KB  |  352 lines  |  [TEXT/????]

  1. /* STDWIN -- EVENTS. */
  2.  
  3. #include "alfa.h"
  4.  
  5. /* There are three levels of event processing.
  6.    The lowest ('raw') level only inputs single characters.
  7.    The middle ('sys') level translates sequences of keys to menu shortcuts
  8.    and 'commands'.
  9.    The highest ('appl') level executes certain commands and can call the
  10.    interactive menu selection code.  It also sets the window parameter.
  11.    For each level there are variants to wait or poll.
  12.    Additional routines to get from one level to another:
  13.    wmapchar: inspect key map and possibly convert char event
  14.    wsyscommand: execute/transform system menu
  15.  
  16. /* Raw event -- read one character.  If blocking is FALSE,
  17.    don't read if trmavail() returns -1, meaning it can't tell whether
  18.    there is input or not.  In that case only synchronous input works. */
  19.  
  20.  
  21. static bool
  22. wrawevent(ep, blocking)
  23.     EVENT *ep;
  24.     bool blocking;
  25. {
  26.     if (!blocking && trmavail() <= 0)
  27.         return FALSE;
  28.     ep->u.character= trminput();
  29.     if (ep->u.character < 0) {
  30.         ep->type= WE_NULL;
  31.         return FALSE;
  32.     }
  33.     else {
  34.         ep->type= WE_CHAR;
  35.         return TRUE;
  36.     }
  37. }
  38.  
  39. static void wmapchar(); /* Forward */
  40.  
  41. /* System event -- read a character and translate using the key map. */
  42.  
  43. bool
  44. wsysevent(ep, blocking)
  45.     EVENT *ep;
  46.     bool blocking;
  47. {
  48.     struct keymap mapentry;
  49.     
  50.     if (!wrawevent(ep, blocking))
  51.         return FALSE;
  52.     /* Using a temporary to avoid a tahoe C compiler bug */
  53.     mapentry= _wprimap[ep->u.character & 0xff];
  54.     wmapchar(ep, mapentry);
  55.     return ep->type != WE_NULL;
  56. }
  57.  
  58. /* Key map translation from raw event.
  59.    This may read more characters if the start of a multi-key sequence is
  60.    found. */
  61.  
  62. static void
  63. wmapchar(ep, mapentry)
  64.     EVENT *ep;
  65.     struct keymap mapentry;
  66. {
  67.     switch (mapentry.type) {
  68.     
  69.     case SHORTCUT:
  70.         ep->type= WE_MENU;
  71.         ep->u.m.id= mapentry.id;
  72.         ep->u.m.item= mapentry.item;
  73.         break;
  74.     
  75.     case SECONDARY:
  76.         if (wrawevent(ep, TRUE)) {
  77.             struct keymap *map;
  78.             struct keymap *altmap= NULL;
  79.             for (map= _wsecmap[mapentry.id];
  80.                 map->type != SENTINEL;
  81.                 ++map) {
  82.                 if (map->key == ep->u.character) {
  83.                     wmapchar(ep, *map);
  84.                     return;
  85.                 }
  86.                 else if (islower(ep->u.character) &&
  87.                     map->key == toupper(ep->u.character))
  88.                     altmap= map;
  89.             }
  90.             if (altmap != NULL) {
  91.                 wmapchar(ep, *altmap);
  92.                 return;
  93.             }
  94.         }
  95.         trmbell();
  96.         ep->type= WE_NULL;
  97.         break;
  98.     
  99.     }
  100. }
  101.  
  102. /* XXX These should be gotten from some $TERM-dependent configuration file */
  103. static char *sense_str = "";
  104. static char *format_str = "";
  105.  
  106. void
  107. wgoto(ep, type)
  108.     EVENT *ep;
  109.     int type;
  110. {
  111.     int h, v;
  112.     
  113.     trmsense(sense_str, format_str, &v, &h);
  114.     if (v >= 0) {
  115.         WINDOW *win;
  116.         for (win= &winlist[1]; win < &winlist[MAXWINDOWS]; ++win) {
  117.             if (win->open && v >= win->top && v < win->bottom) {
  118.                 if (win == front) {
  119.                     ep->type= type;
  120.                     ep->u.where.h= h;
  121.                     ep->u.where.v= v + win->offset;
  122.                     ep->u.where.clicks= 1;
  123.                     ep->u.where.button= 1;
  124.                     ep->u.where.mask=
  125.                         (type == WE_MOUSE_UP ? 0 : 1);
  126.                     return;
  127.                 }
  128.                 wsetactive(win);
  129.                 break;
  130.             }
  131.         }
  132.     }
  133.     ep->type= WE_NULL;
  134. }
  135.  
  136. void
  137. wmouseup(ep)
  138.     EVENT *ep;
  139. {
  140.     int h, v;
  141.     
  142.     trmsense(sense_str, format_str, &v, &h);
  143.     if (v < 0)
  144.         ep->type= WE_NULL;
  145.     else {
  146.         ep->type= WE_MOUSE_UP;
  147.         ep->u.where.h= h;
  148.         ep->u.where.v= v + front->offset;
  149.         ep->u.where.clicks= 1;
  150.         ep->u.where.button= 1;
  151.         ep->u.where.mask= 0;
  152.     }
  153. }
  154.  
  155. static void wdoupdates(); /* Forward */
  156.  
  157. /* Application event. */
  158.  
  159. static EVENT ebuf;
  160.  
  161. void
  162. wungetevent(ep)
  163.     EVENT *ep;
  164. {
  165.     ebuf= *ep;
  166. }
  167.  
  168. bool
  169. wpollevent(ep)
  170.     EVENT *ep;
  171. {
  172.     return wevent(ep, FALSE);
  173. }
  174.  
  175. void
  176. wgetevent(ep)
  177.     EVENT *ep;
  178. {
  179.     (void) wevent(ep, TRUE);
  180. }
  181.  
  182. static bool
  183. wevent(ep, blocking)
  184.     EVENT *ep;
  185.     bool blocking;
  186. {
  187.     static int lasttype= WE_NULL;
  188.     
  189.     if (ebuf.type != WE_NULL) {
  190.         *ep= ebuf;
  191.         ebuf.type= WE_NULL;
  192.         return TRUE;
  193.     }
  194.     
  195.     ep->type= WE_NULL;
  196.     ep->window= NULL;
  197.     if (lasttype == WE_MOUSE_DOWN)
  198.         wmouseup(ep);
  199.     while (ep->type == WE_NULL) {
  200.         if (front != wasfront) {
  201.             if (wasfront != NULL) {
  202.                 ep->type= WE_DEACTIVATE;
  203.                 ep->window= wasfront;
  204.                 wasfront= NULL;
  205.             }
  206.             else {
  207.                 menubarchanged();
  208.                 ep->type= WE_ACTIVATE;
  209.                 wasfront= front;
  210.             }
  211.         }
  212.         else {
  213.             if (trmavail() <= 0)
  214.                 wdoupdates(ep);
  215.             if (ep->type == WE_NULL) {
  216.                 /* Remove this call if no select() exists */
  217.                 if (_w_checktimer(ep, blocking))
  218.                     break;
  219.                 if (!wsysevent(ep, blocking)) {
  220.                     ep->type= WE_NULL;
  221.                     break;
  222.                 }
  223.                 if (ep->type == WE_MENU && ep->u.m.id == 0)
  224.                     wsyscommand(ep);
  225.             }
  226.         }
  227.     }
  228.     if (ep->window == NULL && front != syswin)
  229.         ep->window= front;
  230.     if (ep->type == WE_COMMAND && ep->u.command == WC_CLOSE)
  231.         ep->type= WE_CLOSE; /* Too hard to do earlier... */
  232.     lasttype= ep->type;
  233.     return ep->type != WE_NULL;
  234. }
  235.  
  236. void
  237. wsyscommand(ep)
  238.     EVENT *ep;
  239. {
  240.     ep->type= WE_NULL;
  241.     
  242.     switch (ep->u.m.item) {
  243.     
  244.     default:
  245.         if (ep->u.m.item <= LAST_CMD) {
  246.             ep->type= WE_COMMAND;
  247.             ep->u.command= ep->u.m.item - FIRST_CMD;
  248.         }
  249.         break;
  250.     
  251.     case NEXT_WIN:
  252.         _wselnext();
  253.         break;
  254.     
  255.     case PREV_WIN:
  256.         _wselprev();
  257.         break;
  258.     
  259.     case SUSPEND_PROC:
  260.         _wsuspend();
  261.         break;
  262.     
  263.     case REDRAW_SCREEN:
  264.         _wredraw();
  265.         break;
  266.     
  267.     case MOUSE_DOWN:
  268.     case MOUSE_UP:
  269.         wgoto(ep, ep->u.m.item - MOUSE_DOWN + WE_MOUSE_DOWN);
  270.         break;
  271.     
  272.     case LITERAL_NEXT:
  273.         _wlitnext(ep);
  274.         break;
  275.     
  276.     case MENU_CALL:
  277.         menuselect(ep);
  278.         break;
  279.     
  280.     }
  281. }
  282.  
  283. /* Flush output and place cursor. */
  284.  
  285. void
  286. wflush()
  287. {
  288.     int y= front->curv - front->offset;
  289.     int x= front->curh;
  290.     
  291.     if (front->curv < 0 || y < front->top || y >= front->bottom) {
  292.         y= front->top;
  293.         if (y > 0)
  294.             --y;
  295.         x= 0;
  296.     }
  297.     else if (x < 0)
  298.         x= 0;
  299.     else if (x >= columns)
  300.         x= columns-1;
  301.     trmsync(y, x);
  302. }
  303.  
  304. /* Process pending window updates.
  305.    If a window has no draw procedure, a WE_DRAW event is generated instead. */
  306.  
  307. static void
  308. wdoupdates(ep)
  309.     EVENT *ep;
  310. {
  311.     WINDOW *win;
  312.     int left, top, right, bottom;
  313.     
  314.     for (win= winlist; win < &winlist[MAXWINDOWS]; ++win) {
  315.         if (win->open) {
  316.             if (win->top > 0 && !uptodate[win->top - 1])
  317.                 wdrawtitle(win);
  318.             if (wgetchange(win, &left, &top, &right, &bottom)) {
  319.                 if (win->drawproc == NULL) {
  320.                     ep->type= WE_DRAW;
  321.                     ep->window= win;
  322.                     ep->u.area.left= left;
  323.                     ep->u.area.top= top;
  324.                     ep->u.area.right= right;
  325.                     ep->u.area.bottom= bottom;
  326.                     return;
  327.                 }
  328.                 else {
  329.                     wbegindrawing(win);
  330.                     (*win->drawproc)(win,
  331.                         left, top, right, bottom);
  332.                     wenddrawing(win);
  333.                 }
  334.             }
  335.             if(win->resized) {
  336.                 win->resized = FALSE;
  337.                 ep->type = WE_SIZE;
  338.                 ep->window = win;
  339.                 return;
  340.             }
  341.         }
  342.     }
  343.     wflush();
  344. }
  345.  
  346. void
  347. _wlitnext(ep)
  348.     EVENT *ep;
  349. {
  350.     (void) wrawevent(ep, TRUE);
  351. }
  352.